{% extends "base.html" %}
{% block head %}

<link type="text/css" href="/media/js/openlayers/theme/default/scalebar-thin.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/media/js/openlayers/theme/default/style.css">
<link rel="stylesheet" type="text/css" href="/media/js/jqplot/jquery.jqplot.css" />
<link rel="stylesheet" type="text/css" href="/media/css/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="/media/css/flightDetail.css">
<link rel="stylesheet" type="text/css" href="/media/css/common.css">
<link rel="stylesheet" type="text/css" href="/media/css/timeline.css">
<script src="/media/js/jquery.min.js"></script>
<script src="/media/js/jqplot/jquery.jqplot.min.js"></script>
<script src="/media/js/jqplot/plugins/jqplot.dateAxisRenderer.min.js"></script>
<script src="/media/js/jqplot/plugins/jqplot.canvasOverlay.min.js"></script>
<script src="/media/js/jqplot/plugins/jqplot.cursor.min.js"></script>
<script src="/media/js/openlayers/OpenLayers.js"></script>
<script type="text/javascript" src="/media/js/timeline.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="/media/js/openlayers/lib/Control/ScaleBar.js"></script>
{%if object.flightvideo_set.all %}
<script src="/media/js/swfobject.js"></script>
{% endif %}
<script>

// Setup map stuff
var WGS84 = new OpenLayers.Projection('EPSG:4326');
var MERCATOR = new OpenLayers.Projection('EPSG:900913');
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
var apiKey = "An9cxmMkbbjVOwKKGr8hCIl6N6W30F7VChJdplng1Y12rOJIucGfYMoG5hk6lTct";
var addDataToPlot, addTimelineEvent

$(document).ready(function(){

// Pull all initial data from the DB
latLonsJSON={{object.latLonsJSON}}
//initialPlotData=[[{{object.battVltsDataFlot}}],[{{object.thrDataFlot}}]];
initialPlotData={{initial_plot.data|safe}}
initialPlotLabels={{initial_plot.labels|safe}}
gpsTimestamps={{object.gpsTimestamps|safe}}
tlData = {{timeline_data|safe}}

// Setup the sensor data plot
try{
    min=initialPlotData[0][0][0]
    max=initialPlotData[0].slice(-1)[0][0]
    sensorPlot = $.jqplot('sensorPlot',  initialPlotData, 
        {
            //title:'{{object}}',
            axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer,tickInterval:60},
                //yaxis:{label:initialPlotLabels[0]},
                //y2axis:{label:initialPlotLabels[1]}},
                yaxis:{},
                y2axis:{}},                
            series:[{showMarker:false},{showMarker:false,yaxis:'y2axis'}],
            zoom: true,
            cursor: {
                show: true,
                showVerticalLine: true,
                zoom: true,
            },
            canvasOverlay: {
                show:true,
                objects: [{
                    verticalLine: {
                        name: 'plotCursor',
                        x: min
                        }}]
            }
        }
    );
    // Workaround for bug described at https://bitbucket.org/cleonello/jqplot/issue/633/jqplotdatahighlight-does-not-work-for-line
    sensorPlot.series[0].highlightMouseOver = true;

    $("#sensorPlot").bind("jqinitialPlotDataMouseOver", function(event, srsInd, ptInd, hoveredDatum){
        if(hoveredDatum){
            //Add icon to map for time hoveredDatum[0] (not implemented yet)
        }
    });
}

catch(e){
    alert('Could not draw plot.')
}

//Set the dropdown boxes for plot variables to the ones we load initially
$('select[name="left_axis"] option[value="'+ initialPlotLabels[0] +'"]').prop('selected',true)
$('select[name="right_axis"] option[value="'+ initialPlotLabels[1] +'"]').prop('selected',true)

// Draw videos
    {% for video in object.flightvideo_set.all %}

        var params = { allowScriptAccess: "always" };    
        var atts = { id: "vidPlayer{{video.id}}", class:"vidPlayer" };
        swfobject.embedSWF("{{video.url}}?enablejsapi=1&playerapiid=apiForVid{{video}}&version=3",
                            "vidPlayer{{video.id}}", "425", "356", "8", null, null, params, atts);
    {% endfor %}

// Draw map of flight path
function initMap() {
    // Bing's Road imagerySet
    var broad = new OpenLayers.Layer.Bing({
        key: apiKey,
        type: "Road"
    });
    // Bing's Aerial imagerySet
    var baerial = new OpenLayers.Layer.Bing({
        key: apiKey,
        type: "Aerial"
    });
    // Bing's AerialWithLabels imagerySet
    var bhybrid = new OpenLayers.Layer.Bing({
        key: apiKey,
        type: "AerialWithLabels",
        name: "Bing Aerial With Labels",
        // Ugly custom resolutions are for allowing client zoom. May be a better way.
        resolutions: [156543.03390625, 78271.516953125, 39135.7584765625,
                      19567.87923828125, 9783.939619140625, 4891.9698095703125,
                      2445.9849047851562, 1222.9924523925781, 611.4962261962891,
                      305.74811309814453, 152.87405654907226, 76.43702827453613,
                      38.218514137268066, 19.109257068634033, 9.554628534317017,
                      4.777314267158508, 2.388657133579254, 1.194328566789627,
                      0.5971642833948135, 0.25, 0.1, 0.05],
        serverResolutions: [156543.03390625, 78271.516953125, 39135.7584765625,
                            19567.87923828125, 9783.939619140625,
                            4891.9698095703125, 2445.9849047851562,
                            1222.9924523925781, 611.4962261962891,
                            305.74811309814453, 152.87405654907226,
                            76.43702827453613, 38.218514137268066,
                            19.109257068634033, 9.554628534317017,
                            4.777314267158508, 2.388657133579254,
                            1.194328566789627, 0.5971642833948135],
        transitionEffect: 'resize'
    });

    flightMap = new OpenLayers.Map('map',{projection: MERCATOR,fractionalZoom: true});
    flightMap.addControl(new OpenLayers.Control.LayerSwitcher());
    flightMap.addControl(new OpenLayers.Control.ScaleLine());
    var flightPathFeaturesJSON = {
        "type": "FeatureCollection", 
        "features": [
        {
            "type": "Feature", 
            "geometry":
                {
                    "type": "LineString", 
                    "coordinates": latLonsJSON
                }, 
            
        },]
    };
    var geojson_format = new OpenLayers.Format.GeoJSON({
                    'internalProjection': MERCATOR,
                    'externalProjection': WGS84
                });
    vector_layer = new OpenLayers.Layer.Vector("Flight path",{ style:{strokeColor:"#FF0000",strokeWidth:1, projection: WGS84}});
    curPosLayer = new OpenLayers.Layer.Markers("Current position",{ style:{strokeColor:"#0000FF",strokeWidth:2, projection: WGS84}});
    flightPathFeatures=geojson_format.read(flightPathFeaturesJSON);
    vector_layer.addFeatures(flightPathFeatures);
    flightMap.addLayers([bhybrid, baerial, broad, vector_layer, curPosLayer]);
    flightMap.zoomToExtent(vector_layer.getDataExtent());
    };

initMap();

//Draw the timeline of flight events
function drawTimeline() {
    var options = {
        'width':  '100%',
        'height': '100%',
        'editable': false,
        'style': 'dot',
        'cluster': true,
        'showCustomTime':true
    };
    timeline = new links.Timeline(document.getElementById('timeline'))
    timeline.draw(tlData, options)
    try{
        timeline.setCustomTime(min)
    }
    catch(e){
        alert('Problem seeking timeline to beginning of plot data')
    }
    //Register an event to seek all widgets when the customtime bar is dragged
    links.events.addListener(timeline, 'timechange', onTimelineBarDragged)
};

addTimelineEvent= function() {
    var start = timeline.customTime;
    var content = $("#annotationText").val();

    timeline.addItem({
        'start': start,
        'content': content,
        'group': 'annotations',
    });
    return false;
};

drawTimeline();

// Widget control logic (mostly seeking)
function seekWidgetsTo(seekTime) {
    seekVideoTo(seekTime)
    seekPlotTo(seekTime)
    seekTimelineTo(seekTime)
    seekMapTo(seekTime)
}

getClosestIndex = function(a, x) {
    // This is a binary search, returning the index of the value just below the input x using the list a
    var low = 0, hi = a.length-1;
    while (hi - low > 1) {
        var mid = Math.round((low + hi)/2);
        if (a[mid] <= x) {
            low = mid;
        } else {
            hi = mid;
        }
    }
    if (a[low] == x) hi = low;
    console.log('closest value to ' + x + ' is ' + a[low] + 'at index' + low)
    return low   
}

seekMapTo=function(seekTime) {
    currentPos=latLonsJSON[getClosestIndex(gpsTimestamps,seekTime)]
    curPosMarker=new OpenLayers.Marker(new OpenLayers.LonLat(currentPos).transform(WGS84,MERCATOR), icon.clone())
    curPosLayer.clearMarkers();
    curPosLayer.addMarker(curPosMarker);
    curPosLayer.redraw();
}

function seekPlotTo(seekTime) {
    console.log(seekTime)
    plotCursor=sensorPlot.plugins.canvasOverlay.get('plotCursor')
    plotCursor.options.x=seekTime
    sensorPlot.plugins.canvasOverlay.draw(sensorPlot)
}

function seekVideoTo(seekTime) {
    {% for video in object.flightvideo_set.all %}
        vidStartTime={{video.startTimeJS}}
        //Youtube API takes seconds, JS timestamps are in ms, so divide by 1000
        vidSeekTime=(seekTime-vidStartTime)/1000
        vidPlayer{{video.id}}.seekTo(vidSeekTime)
    {% endfor %}
}

function seekTimelineTo(seekTime) {
    timeline.setCustomTime(seekTime)
}

function onTimelineBarDragged() {
    seekWidgetsTo(timeline.customTime)
}

{% for video in object.flightvideo_set.all %}
seekWidgetsToVidPos{{video.id}}=function() {    
    vidStartTime={{video.startTimeJS}}
    seekTime=vidPlayer{{video.id}}.getCurrentTime()*1000+vidStartTime
    console.log('trying to seek to time ' + parseInt(seekTime))
    seekPlotTo(seekTime)
    seekTimelineTo(seekTime)
    seekMapTo(seekTime)
}

onPlayer{{video.id}}StateChange = function (newstate) {
    // If we just started playing
    console.log("video state changed")
    if (newstate==1){
        console.log('started playing')
        vidSeekPoller=setInterval(seekWidgetsToVidPos{{video.id}}, 250)
    }
    else {
        console.log('stopped playing')
        clearInterval(vidSeekPoller)
    }
}

{% endfor %}
$("#detailsContainer").tabs() // activate jquery ui tabs
//$("#plotContainer").tabs() 
addDataToPlot = function() {
    $.ajax({
        type:'GET',
        url:'/data',
        data:$('#sensorPlotDataForm').serialize(),
        }).done(function (data) {
            sensorPlot.replot({data:data})
            data=data
            })
    return false
}

function annotateTimeline(evt) {
    evt.preventDefault();
    timeline.addItem({
        'start': timeline.customTime,
        'content': $('#annotationText').val(),
        'group': 'Annotations'
    });

    var count = data.getNumberOfRows();
    timeline.setSelection([{
        'row': count-1
    }]);
    return false
}

$('#sensorPlotDataForm').submit(addDataToPlot)
$('#timelineController form').submit(annotateTimeline)
}); // end of jquery document.ready function

function onYouTubePlayerReady(playerId) {
{% for video in object.flightvideo_set.all %}
    
    vidPlayer{{video.id}} = document.getElementById("vidPlayer{{video.id}}");
    vidPlayer{{video.id}}.addEventListener("onStateChange","onPlayer{{video.id}}StateChange");
    console.log("added event listener")
{% endfor %}
}

function addVideoToTimeline() {
    //TODO make this handle multiple videos
    {% if flight.flightVideo_set.0 %}
        startime={{flight.flightVideo_set.0.startTime}}
        endtime={{flight.flightVideo_set.0.startTime}}+ytplayer.getDuration()
    {% endif %}
}
</script>
{% endblock head %}

{% block nav-status %}Viewing flight "{{object}}"{% endblock %}

{% block content %}
<div id="detailsContainer">

<ul>
<li><a href="#detailsContainer-1">Flight notes</a></li>
<li><a href="#detailsContainer-2">Log summary</a></li>
<li><a href="#detailsContainer-3">Parameters</a></li>
<li><a href="#detailsContainer-4">Flight analysis</a></li>
</ul>
<div class="tabs-background ui-widget-header"><h2>Flight details</h2></div>
<div id="detailsContainer-1">
    <table>
    <tr><td>Logfile:</td> <td>{{object.logfile}}</td>
    <tr><td>Notes:</td> <td>{{object.comments|default:"Not specified"}}</td>
    <tr><td>Pilot:</td> <td>{{object.pilot|default:"Not specified"}}</td>
    <tr><td>Airframe:</td> <td>{{ object.airframe|default:"Not specified"}}</td>
    <tr><td>Battery:</td> <td>{{object.battery|default:"Not specified"}}</td>
    <tr><td>Payload:</td> <td>{{object.payload|default:"Not specified"}}</td>
    </table>
    
</div>
<div id="detailsContainer-2">
        Total log messages: {{object.mavmessage_set.count}}
        <table>
        {% for messageType in object.countMessagesByType %}
        <tr><td>{{messageType.0}}:</td><td> {{messageType.1}}</td></tr>
        {% endfor %}
        </table>
    
</div>
<div id="detailsContainer-3">
    Not implemented yet.
    
</div>
<div id="detailsContainer-4">
    Not implemented yet.
    
</div>
</div>
<div id="videoContainer">
    <h2>Video</h2>
    
    {% for video in object.flightvideo_set.all %}
        <div id="vidPlayer{{video.id}}"></div>
    {% endfor %}
    
</div>
<div id="plotContainer">
    <h2>Sensor data</h2>
        <div id="sensorPlot"></div>
        <form id="sensorPlotDataForm">
            <p>Left y axis:
            <select name="left_axis">
                {% for msg_field in object.messageFieldsRecorded %}
                    <option value="{{msg_field}}">{{msg_field}}</option>
                {% endfor %}
            </select></p>
            <p>Right y axis:
            <select name="right_axis">
                {% for msg_field in object.messageFieldsRecorded %}
                    <option value="{{msg_field}}">{{msg_field}}</option>
                {% endfor %}
            </select></p>
            <input type="hidden" name="flight" value="{{object}}" />
            <input type="submit" value="Update plot"></input>
        </form>
        <button onclick="sensorPlot.resetZoom()">Reset zoom</button>
</div>
<div id="mapContainer">
    <h2>Map</h2>
    <div id="map"></div>
</div>
<div id="timelineContainer">
    <h2>Flight event timeline</h2>
    <div id="timelineController">
        <form>
        <input type="text" value="Annotation text" id="annotationText"></input>
        <input type="submit" value="Add annotation at blue time bar"></submit>
        <input type="submit" value="Save annotations"></submit>
        </form>
    </div>
    <div id="timeline">Timeline loading...</div>
</div>


</div>
{% endblock content %}